﻿//using System.Collections.Generic;
//using System.Collections.ObjectModel;
//using System.Data;
//using System.Data.Entity;
//using System.Linq;
//using UCosmic.Domain;
//using UCosmic.Domain.Places;
//using UCosmic.Orm;

//namespace UCosmic.Storage
//{
//    public class PlaceStorage : IStorePlaces
//    {
//        #region Construction & DI

//        public IUnitOfWork UnitOfWork { get; private set; }

//        private UCosmicContext DbContext
//        {
//            get { return UnitOfWork as UCosmicContext; }
//        }

//        public PlaceStorage(IUnitOfWork unitOfWork)
//        {
//            UnitOfWork = unitOfWork;
//        }

//        #endregion

//        public IEnumerable<Place> FindMany(PlaceFinder finder)
//        {
//            // do not track entities returned by find methods
//            var query = DbContext.Places.AsQueryable();

//            // initialize finder
//            if (finder == null)
//                finder = new PlaceFinder();

//            // apply context tracking
//            if (!finder.IsForInsertOrUpdate)
//                query = query.AsNoTracking();

//            // apply includes
//            var includes = finder.ToBeEagerLoaded;
//            if (includes != null && includes.Count > 0)
//                query = finder.ToBeEagerLoaded.Aggregate(query, (lastInclude, nextInclude) =>
//                    lastInclude.Include(nextInclude));

//            // apply geoNameId
//            if (finder.GeoNameId.HasValue)
//                query = query.Where(e => e.GeoNamesToponym != null
//                    && e.GeoNamesToponym.GeoNameId == finder.GeoNameId.Value);

//            // apply woeId
//            if (finder.WoeId.HasValue)
//                query = query.Where(e => e.GeoPlanetPlace != null
//                    && e.GeoPlanetPlace.WoeId == finder.WoeId.Value);

//            var found = query.ToList();
//            return found;
//        }

//        public Place FindOne(PlaceFinder finder)
//        {
//            return FindMany(finder).SingleOrDefault();
//        }

//        public void Insert(Place place)
//        {
//            if (place == null) return;

//            RefreshNodeHierarchy(place);

//            DbContext.Places.Add(place);
//        }

//        private void RefreshNodeHierarchy(Place place)
//        {
//            place.Ancestors = place.Ancestors ?? new Collection<PlaceNode>();
//            place.Offspring = place.Offspring ?? new Collection<PlaceNode>();

//            place.Ancestors.ToList().ForEach(node =>
//                DbContext.Entry(node).State = EntityState.Deleted);

//            var separation = 1;
//            var parent = place.Parent;
//            while (parent != null)
//            {
//                place.Ancestors.Add(new PlaceNode
//                {
//                    Ancestor = parent, Separation = separation++,
//                });
//                parent = parent.Parent;
//            }
//        }

//    }
//}